{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HxxOWz9dpsYj"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/drive/1h-YPHGKgrqaM7e5OoM_AHGyK2z5eHd1o?usp=sharing\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>\n",
        "\n",
        "\n",
        "### 📚 Prompt Engineering\n",
        "\n",
        "[Prompt Engineering](https://www.promptingguide.ai/introduction) is the **art** and **science** of crafting effective inputs for Large Language Models (LLMs) to produce desired outputs. It's a crucial skill in GenAI related tasks, allowing users to harness the full potential of Large Language Models (LLMs) for various tasks.\n",
        "\n",
        "------------\n",
        "\n",
        "#### 📖 Fundamentals of Prompt Design\n",
        "\n",
        "  * #### ✨ Clarity\n",
        "    * Be specific and unambiguous in your instructions.\n",
        "\n",
        "  * #### 🏛️ Context\n",
        "    * Provide relevant background information.\n",
        "\n",
        "  * #### 🚧 Constraints\n",
        "    * Set boundaries for the AI's response.\n",
        "\n",
        "  * #### 🧪 Examples\n",
        "    * Include sample inputs and outputs when possible.\n",
        "\n",
        "  * #### 🗂️ Format\n",
        "    * Specify the desired structure of the response.\n",
        "\n",
        "------------\n",
        "<br>\n",
        "\n",
        "<img width=\"700\" src=\"https://raw.githubusercontent.com/genieincodebottle/generative-ai/main/images/Prompt_engineering.png\">\n",
        "\n",
        "### 📌 Important Prompt Techniques you should know\n",
        "\n",
        "  1. #### 🧠 Chain of Thought (CoT)\n",
        "    * A strategy to enhance reasoning by articulating intermediate steps.\n",
        "\n",
        "  2. #### 🚀 Zero-Shot Chain of Thought (Zero-Shot-CoT)\n",
        "    * Applying CoT without prior examples or training on similar tasks.\n",
        "\n",
        "  3. #### 🎯 Few-Shot Chain of Thought  (Few-Shot-CoT)\n",
        "    * Using a few examples to guide the reasoning process.\n",
        "\n",
        "  4. #### 🤔 ReAct (Reasoning and Acting)\n",
        "    * Combining reasoning with action to improve responses.\n",
        "\n",
        "  5. #### 🌳 Tree of Thoughts (ToT)\n",
        "    * Organizing thoughts hierarchically for better decision-making.\n",
        "\n",
        "  6. #### 🔄 Self-Consistency\n",
        "    * Ensuring responses are stable and consistent across queries.\n",
        "\n",
        "  7. #### 📄 Hypothetical Document Embeddings (HyDE)\n",
        "    * Leveraging embeddings to represent potential documents for reasoning.\n",
        "\n",
        "  8. #### 🏗️ Least-to-Most Prompting\n",
        "    * Starting with simpler prompts and gradually increasing complexity.\n",
        "\n",
        "  9. #### 🔗 Prompt Chaining\n",
        "    * Connecting multiple prompts to create a coherent narrative.\n",
        "\n",
        "  10. #### 📊 Graph Prompting\n",
        "    * Using graph structures to represent complex relationships.\n",
        "\n",
        "  11. #### 🔄 Recursive Prompting\n",
        "    * Iteratively refining prompts to enhance results.\n",
        "\n",
        "  12. #### 💡 Generated Knowledge\n",
        "    * Utilizing generated content as a basis for further reasoning.\n",
        "\n",
        "  13. #### ⚙️ Automatic Reasoning and Tool-Use (ART)\n",
        "    * Automating reasoning processes and tool interactions.\n",
        "\n",
        "  14. #### 🛠️ Automatic Prompt Engineer (APE)\n",
        "    * Tools to automatically generate and refine prompts.\n",
        "\n",
        "  15. #### ✨ Additional Prompt Techniques\n",
        "    * **Reflexion**: Reflecting on past responses to improve future prompts.\n",
        "    \n",
        "    * **Prompt Ensembling**: Combining multiple prompts for enhanced results.\n",
        "    \n",
        "    * **Directional Stimulus Prompting**: Guiding responses with targeted prompts.\n",
        "\n",
        "------------\n",
        "<br>\n",
        "\n",
        "### 📈 Prompt Optimization Techniques\n",
        "\n",
        "1. **Iterative refinement:** Start with a basic prompt and gradually improve it based on the results.\n",
        "\n",
        "2. [**A/B testing:**](https://www.oracle.com/in/cx/marketing/what-is-ab-testing/#:~:text=A%2FB%20testing%3F-,A%2FB%20testing%20definition,based%20on%20your%20key%20metrics.) Compare different versions of a prompt to see which performs better.\n",
        "\n",
        "3. **Prompt libraries:** Create and maintain a collection of effective prompts for reuse.\n",
        "\n",
        "4. **Collaborative prompting:** Combine insights from multiple team members to create stronger prompts.\n",
        "------------\n",
        "<br>\n",
        "\n",
        "### ⚖️ Ethical Considerations in Prompt Engineering\n",
        "\n",
        "1. **Bias mitigation:** Be aware of and actively work to reduce biases in prompts and outputs.\n",
        "\n",
        "2. **Content safety:** Implement safeguards against generating harmful or inappropriate content.\n",
        "\n",
        "4. **Data privacy:** Avoid including sensitive information in prompts.\n",
        "------------\n",
        "<br>\n",
        "\n",
        "### ✅ Evaluating Prompt Effectiveness\n",
        "\n",
        "1. **Relevance:** Does the output address the intended task or question?\n",
        "\n",
        "2. **Accuracy:** Is the information provided correct and up-to-date?\n",
        "\n",
        "3. **Coherence:** Is the response well-structured and logical?\n",
        "\n",
        "4. **Creativity:** For open-ended tasks, does the output demonstrate originality?\n",
        "\n",
        "5. **Efficiency:** Does the prompt produce the desired result with minimal back-and-forth?\n",
        "\n",
        "------------\n",
        "<br>\n",
        "\n",
        "### ⚙️ Setup\n",
        "\n",
        "* **[LLM](https://console.groq.com):** Groq's free api endpoint ([Groq API Key](https://console.groq.com/keys))\n",
        "\n",
        "* **[LLM Framework](https://python.langchain.com/v0.2/docs/introduction/):** LangChain\n",
        "------------\n",
        "\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Y3axTI0sp5Hg"
      },
      "source": [
        "### 📦 Install required libraries"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "collapsed": true,
        "id": "ShxTNxM5gqtr",
        "outputId": "243868e7-5663-474b-83ba-f45e73122c24"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\u001b[?25l   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/121.9 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K   \u001b[91m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[91m╸\u001b[0m\u001b[90m━━━\u001b[0m \u001b[32m112.6/121.9 kB\u001b[0m \u001b[31m6.1 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m121.9/121.9 kB\u001b[0m \u001b[31m2.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h"
          ]
        }
      ],
      "source": [
        "!pip install -q -U langchain-groq==0.2.4"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9jJ1vqs-p_Zx"
      },
      "source": [
        "### 📥 Import related libraries"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "RL-3LsYogoH5"
      },
      "outputs": [],
      "source": [
        "from langchain_groq import ChatGroq\n",
        "from langchain.prompts import ChatPromptTemplate"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import os\n",
        "import getpass"
      ],
      "metadata": {
        "id": "7psYXg6sHkOo"
      },
      "execution_count": 3,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "F6UeDlrgqI2A"
      },
      "source": [
        "### 🔑 Provide Groq API Key\n",
        "\n",
        "1. [Groq API Key](https://console.groq.com/keys)\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "yobvrD3glfd4",
        "outputId": "45d9ef6e-ab34-4f54-e449-d6b5e30c5bf0"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "··········\n"
          ]
        }
      ],
      "source": [
        "os.environ[\"GROQ_API_KEY\"] = getpass.getpass()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "id": "Ye3dDZF0IJzP"
      },
      "outputs": [],
      "source": [
        "llm = ChatGroq(\n",
        "    model=\"llama3-8b-8192\",\n",
        "    temperature=0.5\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {
        "id": "BjwoJ_pR7nD1"
      },
      "outputs": [],
      "source": [
        "chat_prompt = ChatPromptTemplate.from_messages(\n",
        "    [\n",
        "        (\"system\", \"You are a helpful assistant that explains problems step-by-step.\"),\n",
        "        (\"human\", \"Solve this problem step by step: {input}\"),\n",
        "    ]\n",
        ")\n",
        "\n",
        "chain = chat_prompt | llm"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "ai_msg = chain.invoke({\"input\": \"Provide me python code of sudoku\"})\n",
        "print(ai_msg.content)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "05wWoAc_lLsI",
        "outputId": "a74c3f99-6ec3-4464-f4eb-bd8676ac9675"
      },
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "I can help you with that. Here's a step-by-step explanation of how to solve a Sudoku problem using Python:\n",
            "\n",
            "**Step 1: Define the Sudoku Board**\n",
            "\n",
            "A Sudoku board is a 9x9 grid, divided into nine 3x3 sub-grids or \"regions.\" Some of the cells may contain numbers, while others are blank. We'll represent the board as a 2D list in Python.\n",
            "\n",
            "```\n",
            "sudoku_board = [\n",
            "    [5,3,0,0,7,0,0,0,0],\n",
            "    [6,0,0,1,9,5,0,0,0],\n",
            "    [0,9,8,0,0,0,0,6,0],\n",
            "    [8,0,0,0,6,0,0,0,3],\n",
            "    [4,0,0,8,0,3,0,0,1],\n",
            "    [7,0,0,0,2,0,0,0,6],\n",
            "    [0,6,0,0,0,0,2,8,0],\n",
            "    [0,0,0,4,1,9,0,0,5],\n",
            "    [0,0,0,0,8,0,0,7,9]\n",
            "]\n",
            "```\n",
            "\n",
            "**Step 2: Define the is_valid function**\n",
            "\n",
            "This function checks if a number is valid for a given position on the board. It checks if the number already exists in the same row, column, or region.\n",
            "\n",
            "```\n",
            "def is_valid(board, row, col, num):\n",
            "    for x in range(9):\n",
            "        if board[row][x] == num:\n",
            "            return False\n",
            "             \n",
            "    for x in range(9):\n",
            "        if board[x][col] == num:\n",
            "            return False\n",
            " \n",
            "    start_row = row - row % 3\n",
            "    start_col = col - col % 3\n",
            "    for i in range(3):\n",
            "        for j in range(3):\n",
            "            if board[i + start_row][j + start_col] == num:\n",
            "                return False\n",
            "    return True\n",
            "```\n",
            "\n",
            "**Step 3: Define the solve function**\n",
            "\n",
            "This function uses backtracking to solve the Sudoku puzzle. It starts from the top-left corner and tries to fill in the board with numbers. If it finds a position that cannot be filled, it backtracks and tries a different number.\n",
            "\n",
            "```\n",
            "def solve(board):\n",
            "    for i in range(9):\n",
            "        for j in range(9):\n",
            "            if board[i][j] == 0:\n",
            "                for num in range(1, 10):\n",
            "                    if is_valid(board, i, j, num):\n",
            "                        board[i][j] = num\n",
            "                        if solve(board):\n",
            "                            return True\n",
            "                        board[i][j] = 0\n",
            "                return False\n",
            "    return True\n",
            "```\n",
            "\n",
            "**Step 4: Call the solve function**\n",
            "\n",
            "Finally, we call the solve function to solve the Sudoku puzzle.\n",
            "\n",
            "```\n",
            "if solve(sudoku_board):\n",
            "    for i in range(9):\n",
            "        print(sudoku_board[i])\n",
            "else:\n",
            "    print(\"No solution exists\")\n",
            "```\n",
            "\n",
            "**Step 5: Run the code**\n",
            "\n",
            "You can run this code and it will print out the solved Sudoku puzzle.\n",
            "\n",
            "Here's the complete code:\n",
            "\n",
            "```\n",
            "def is_valid(board, row, col, num):\n",
            "    for x in range(9):\n",
            "        if board[row][x] == num:\n",
            "            return False\n",
            "             \n",
            "    for x in range(9):\n",
            "        if board[x][col] == num:\n",
            "            return False\n",
            " \n",
            "    start_row = row - row % 3\n",
            "    start_col = col - col % 3\n",
            "    for i in range(3):\n",
            "        for j in range(3):\n",
            "            if board[i + start_row][j + start_col] == num:\n",
            "                return False\n",
            "    return True\n",
            "\n",
            "def solve(board):\n",
            "    for i in range(9):\n",
            "        for j in range(9):\n",
            "            if board[i][j] == 0:\n",
            "                for num in range(1, 10):\n",
            "                    if is_valid(board, i, j, num):\n",
            "                        board[i][j] = num\n",
            "                        if solve(board):\n",
            "                            return True\n",
            "                        board[i][j] = 0\n",
            "                return False\n",
            "    return True\n",
            "\n",
            "sudoku_board = [\n",
            "    [5,3,0,0,7,0,0,0,0],\n",
            "    [6,0,0,1,9,5,0,0,0],\n",
            "    [0,9,8,0,0,0,0,6,0],\n",
            "    [8,0,0,0,6,0,0,0,3],\n",
            "    [4,0,0,8,0,3,0,0,1],\n",
            "    [7,0,0,0,2,0,0,0,6],\n",
            "    [0,6,0,0,0,0,2,8,0],\n",
            "    [0,0,0,4,1,9,0,0,5],\n",
            "    [0,0,0,0,8,0,0,7,9]\n",
            "]\n",
            "\n",
            "if solve(sudoku_board):\n",
            "    for i in range(9):\n",
            "        print(sudoku_board[i])\n",
            "else:\n",
            "    print(\"No solution exists\")\n",
            "```\n",
            "\n",
            "This code will solve the Sudoku puzzle and print out the solved board.\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "b81XnftomEu2"
      },
      "execution_count": null,
      "outputs": []
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}